import json

from django.db import transaction
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View

from apps.goods.models import SKU
from apps.orders.models import OrderInfo, OrderGoods
from utlis.views import LoginRequiredJSONMixin
from apps.areas.models import Address
from django_redis import get_redis_connection


class ShowOrdersView(LoginRequiredJSONMixin, View):
    def get(self, request):
        user = request.user
        # 获取用户地址信息
        addresses = Address.objects.filter(user=user, is_deleted=False)
        addresses_list = []
        for address in addresses:
            addresses_list.append({
                'id': address.id,
                'province': address.province.name,
                'city': address.city.name,
                'district': address.district.name,
                'place': address.place,
                'receiver': address.receiver,
                'mobile': address.mobile
            })

        # 从redis获取购物车所有被勾选的商品信息
        redis_cli = get_redis_connection('carts')
        pipeline = redis_cli.pipeline()
        pipeline.hgetall('carts_%s' % user.id)
        pipeline.smembers('selected_%s' % user.id)
        result = pipeline.execute()
        sku_id_count = result[0]  # b{sku_id:count,sku_id:count}
        selected_ids = result[1]  # [1,2]
        selected_carts = {}
        for sku_id in selected_ids:
            # 组织数据
            # selected_carts={sku_id:count}
            selected_carts[int(sku_id)] = int(sku_id_count[sku_id])
        # 获取商品信息
        sku_list = []
        skus = SKU.objects.filter(id__in=selected_carts.keys())
        for sku in skus:
            sku_list.append({
                'id': sku.id,
                'name': sku.name,
                'count': selected_carts[sku.id],
                'default_image_url': sku.default_image.url,
                'price': sku.price
            })
        # 运费
        from decimal import Decimal
        freight = Decimal('10.00')

        # 组织返回数据
        context = {
            'addresses': addresses_list,
            'skus': sku_list,
            'freight': freight,
        }

        return JsonResponse({'code': 0, 'errmsg': 'ok', 'context': context})







class CommitView(LoginRequiredJSONMixin, View):
    """订单提交"""

    def post(self, request):
        """保存订单信息"""
        # 接收参数
        user = request.user
        data = json.loads(request.body.decode())
        address_id = data.get('address_id')
        pay_method = data.get('pay_method')
        # 验证参数
        if not all([address_id, pay_method]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})
        try:
            address = Address.objects.get(id=address_id)
        except Address.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': '参数不正确'})
        if pay_method not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY'], ]:
            return JsonResponse({'code': 400, 'errmsg': '参数不正确'})

        from django.utils import timezone
        # 生成订单id 生成时间加九位数用户id
        order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + '%09d' % user.id
        # 选择支付
        if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH']:
            status = OrderInfo.ORDER_STATUS_ENUM['UNSEND']
        else:
            status = OrderInfo.ORDER_STATUS_ENUM['UNPAID']

        # 商品总数
        total_count = 0
        from decimal import Decimal
        # 商品总金额
        total_amount = Decimal('0')
        # 运费
        freight = Decimal('10.00')
        with transaction.atomic():
            # 事物开始
            point = transaction.savepoint()
            # 数据入库
            orderinfo = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_count=total_count,
                total_amount=total_amount,
                freight=freight,
                pay_method=pay_method,
                status=status
            )
            """订单商品信息"""
            # 连接redis
            redis_cli = get_redis_connection('carts')
            carts_dict = redis_cli.hgetall('carts_%s' % user.id)
            selected_ids = redis_cli.smembers('selected_%s' % user.id)
            # 从redis获取的购物车中已勾选商品
            carts = {}  # carts={sku_id{count:1,count:2}}
            for sku_id in selected_ids:
                carts[int(sku_id)] = int(carts_dict[sku_id])

            # 查询数据库
            for sku_id, count in carts.items():
                for i in range(10):
                    sku = SKU.objects.get(id=sku_id)
                    # 如果数据库不充足
                    if sku.stock < count:
                        # 回滚事物
                        transaction.savepoint_rollback(point)
                        return JsonResponse({'code': 400, 'errmsg': '下单失败'})
                    # # 库存减少
                    # sku.stock -= count
                    # # 销量增加
                    # sku.sales += count
                    # sku.save()
                    import time
                    old_sales = sku.sales
                    old_stock = sku.stock

                    new_stock = old_stock-count
                    new_sales = old_sales+count
                    time.sleep(0.25)
                    result = SKU.objects.filter(id=sku_id,stock=old_stock).update(stock=new_stock,sales=new_sales)
                    if result == 0:
                        continue

                        # 计算总金额
                    orderinfo.total_count += count

                    orderinfo.total_amount += (count * sku.price)

                    orderinfo.total_amount+=orderinfo.freight
                    # 数据入库 保存订单商品信息
                    OrderGoods.objects.create(
                        order=orderinfo,
                        sku=sku,
                        count=count,
                        price=sku.price
                    )
                    break
            orderinfo.save()
            transaction.savepoint_commit(point)
            # 清除已结算的购物车
            pl = redis_cli.pipeline()
            sku_ids = carts.keys()
            pl.hdel('carts_%s' % user.id, *sku_ids)
            pl.srem('selected_%s' % user.id, *sku_ids)
            pl.execute()

        return JsonResponse({'code': 0, 'errmsg': 'ok', 'order_id': order_id})
